package com.nuc.zyt.day03.Lambda;

import java.util.Comparator;

/**
 * @ClassName HelloLambda
 * @Description TODO
 * @Author 耀酱
 * @Date 2023/5/18 20:16
 * @Version 1.0
 */

public class HelloLambda {
    //Lambda表达式在身份上与匿名类对象等价 Lambda表达式在作用上与方法等价。Lambda表达式其实就是把行为参数化（方法作为参数传递）。

        public static void main(String[] args) {
            String str1 = "abc";
            String str2 = "abcd";

            // 上面推导得出Lambda表达式与匿名类对象等价，所以我们可以把Lambda表达式赋值给Comparator接口
            Comparator<String> comparator = (String s1, String s2) -> {
                return s1.length() - s2.length();
            };
            // 调用
            int k = compareString(str1, str2, comparator);

            int i = compareString(str1, str2, new Comparator<String>() {
                @Override
                public int compare(String o1, String o2) {
                    return 0;
                }
            });
            // Lambda表达式 = 形参列表 + 方法体
            int i1 = compareString(str1, str2, (s1, s2) -> s1.length() - s2.length());
            // 方法引用
            int i2 = compareString(str1, str2, Comparator.comparingInt(String::length));

            /**
             * 对于匿名内部类而言，类名、方法名真的没什么用。只有当一个方法需要被使用多次时，我们才需要为它命名，
             * 以便其他程序通过方法名重复调用。而匿名内部类的性质就是仅调用一次，所以名字对它来说是可有可无的。
             * 至于返回值与形参类型，Lambda都可以通过上下文推断，所以也可以省略：
             */

            /**
             * 显然不是的，接口要想接收Lambda表达式，必须是一个函数式接口。所谓函数式接口，最核心的特征是：有且只有一个抽象方法。
             * 也就是说，如果你希望一个接口能接收Lambda表达式充当匿名类对象，那么接口必须仅有一个抽象方法，这是函数式接口的定义。
             * 通常我们可以在接口上加一个@FunctionalInterface检测，
             * 作用于@Override一样。但函数式接口和@FunctionalInterface注解没有必然联系，只要这个接口符合函数式接口的定义，它就是函数式接口。
             */

            /**
             * 这就是我所谓的“方法多态”：通过函数式接口把形参的坑占住，后续传入不同的Lambda实现各自逻辑。
             */

            /**
             * 不论具体实现类、匿名类还是Lambda表达式，其实做的事情本质上是一样的：
             * 1.先让函数式接口占坑
             * 2.自己不慌不忙制定映射规则，规则可以被藏在具体类、匿名类中，或者Lambda表达式本身
             */


            System.out.println(k);





        }

        public static int compareString(String str1, String str2, Comparator<String> comparator) {
            return comparator.compare(str1, str2);
        }

}
